package cn.yunyichina.provider.clinic.service.impl;

import cn.yunyichina.provider.clinic.constant.CacheConstant;
import cn.yunyichina.provider.clinic.dao.ClinicRecordDao;
import cn.yunyichina.provider.clinic.hisiface.vo.ClinicVo;
import cn.yunyichina.provider.clinic.vo.AckPayOrderOutVoRequest;
import cn.yunyichina.provider.framework.annotation.validate.ValidateException;
import cn.yunyichina.provider.framework.annotation.validate.Validator;
import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.dubbo.service.*;
import cn.yunyichina.provider.iface.entity.PersonalUser;
import cn.yunyichina.provider.iface.entity.base.OrderExceptionVo;
import cn.yunyichina.provider.iface.entity.base.OrderExtVo;
import cn.yunyichina.provider.iface.entity.base.Org;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.common.TestFlag;
import cn.yunyichina.provider.iface.entity.hisiface.clinic.*;
import cn.yunyichina.provider.iface.entity.message.ImageTemplateListVo;
import cn.yunyichina.provider.iface.entity.message.ImageTemplateVo;
import cn.yunyichina.provider.iface.entity.message.OrgAppTemplateVo;
import cn.yunyichina.provider.iface.entity.pay.PaymentJournalVo;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.convert.ObjectParser;
import cn.yunyichina.utils.network.HttpsUtil;
import cn.yunyichina.utils.security.MD5Util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class PayServiceImpl {

    private Logger logger = LoggerFactory.getLogger(PayServiceImpl.class);

    @Autowired
    private ClinicRecordDao clinicRecordDao;

    @Resource
    private Properties yaml;

    private final String TEMPLATECODE = "22012";
    private final String IMG_TEMPLATECODE="IMG22012";

    /**
     * 门诊已缴费列表查询 - 外部接口 yyt.clinic.pay.out.list
     * 
     * @param data
     * @param sessionId
     * @return
     */
    public Response listPayOut(String data, String sessionId) {
        logger.info("门诊已缴费列表查询, 方法入参data=" + data + ", sessionId=" + sessionId);
        Response response = new Response();
        
        ClinicVo clinicVo = JsonUtils.parseObject(data, ClinicVo.class);
        PayVo payvo = new PayVo();
        if(StringUtils.isNotBlank(clinicVo.getPsOrdnum())) {
            // 找出对应数据库保存的门诊记录
//            ClinicRecord wheres = new ClinicRecord();
//            wheres.setOutOrderNo(clinicVo.getPsOrdnum());
//            List<ClinicRecord> clinicRecords = clinicRecordDao.select(wheres);
            
            Map<String, String> dataMap = new HashMap<String, String>();
            dataMap.put("out_order_no", clinicVo.getPsOrdnum());
            logger.info("门诊已缴费列表查询, 订单号" + clinicVo.getPsOrdnum() + ", 调base模块, 查询订单接口入参request="
                    + JSON.toJSONString(dataMap));
            Response ordResponse = BaseService.callUnderlineFromInternal(sessionId,
                    "yyt.base.order.by.order.no.out.get", JsonUtils.toJsonString(dataMap));
            logger.info("门诊已缴费列表查询, 订单号" + clinicVo.getPsOrdnum() + ", 调base模块, 查询订单接口返回response="
                    + JSON.toJSONString(ordResponse));
            if (!"0".equals(ordResponse.getResultCode())) {
                response.setResultCodeAndMessage("999", "查询订单异常。");
                return response;
            }
            OrderExtVo vo = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);
            
//            ClinicRecord clinicRecord = clinicRecords.get(0);
//            logger.info("listPayOut, clinicRecord=" + JSONObject.toJSONString(clinicRecord));
            
            payvo.setHospitalCode(clinicVo.getHospitalCode());
            payvo.setBranchCode(clinicVo.getBranchCode());
            payvo.setPatCardNo(clinicVo.getPatCardNo());
            payvo.setPatCardType(clinicVo.getPatCardType() == null ? "1" : String.valueOf(clinicVo.getPatCardType()));
            payvo.setPayMode(clinicVo.getPayMode() == null ? "5" : String.valueOf(clinicVo.getPayMode()));
            payvo.setBeginDate(clinicVo.getBeginDate());
            payvo.setEndDate(clinicVo.getEndDate());
            payvo.setYytOrdNum(vo.getOrderNo());
            payvo.setSessionId(sessionId);
        }
        
        logger.info("门诊已缴费列表查询, 订单号" + payvo.getYytOrdNum() + ", 调hisiface模块, 查询已缴费列表入参request="
                + JSONObject.toJSONString(payvo));
        ResCommon<List<PayVoResponse>> payResponse = HisifaceService.getHisifaceClient().listClinicPay(payvo);
        logger.info("门诊已缴费列表查询, 订单号" + payvo.getYytOrdNum() + ", 调hisiface模块, 查询已缴费列表返回response="
                + JSONObject.toJSONString(payResponse));
        if (!ResCommon.SUCCESS_CODE.equals(payResponse.getResultCode())) {
            response.setResultCodeAndMessage("3000",
                    "查询就诊卡号" + payvo.getPatCardNo() + "对应的已缴费列表失败：" + payResponse.getResultMessage() + "！");
            return response;
        }
        
        List<PayVoResponse> payVoResponses = JsonUtils.parseObject(payResponse.getResult(), List.class);
        logger.info("门诊已缴费列表查询, 订单号" + payvo.getYytOrdNum() + ", 查询已缴费列表返回结构体中，结果内容result="
                + JSON.toJSONString(payVoResponses));
        if (CollectionUtils.isEmpty(payVoResponses)) {
            response.setResultCodeAndMessage("3002", "不存在已缴费记录！");
            return response;
        } else {
            response.setResult(JsonUtils.toJsonString(payVoResponses));
        }
        logger.info("门诊已缴费列表查询, 方法出参response=" + JsonUtils.toJsonString(response));
        return response;
    }

    /**
     * 门诊支付写单 - 外部接口 yyt.clinic.pay.order.out.ack
     * @author zhangkewen
     * @param data
     * @param sessionId
     * @return
     */
    public Response ackPayOrderOut(String data, String sessionId) {

        Response response = new Response();
        logger.info("门诊支付写单外部接口, 方法入参data=" + data);
        
        // 转换成-->RequestVo
        AckPayOrderOutVoRequest requestVo = JsonUtils.parseObject(data, AckPayOrderOutVoRequest.class);

        // 校验RequestVo的数据
        try {
            Validator.getInstance().validate(requestVo);
        } catch (ValidateException ex) {
            logger.info("门诊支付写单外部接口, 数据校验失败:" + ex.getMessage() + " | 方法入参:" + data + "！");
            response.setResultCodeAndMessage("3001", "数据校验失败:" + ex.getMessage() + "！");
            return response;
        }
        
        
        // 找出对应数据库保存的门诊记录getOrderByOrderNo
        Map<String, String> dataMap = new HashMap<String, String>();
        dataMap.put("order_no", requestVo.getYytOrderNo());

        if (StringUtils.isNotBlank(requestVo.getHospitalCode())) {
            Map<String, String> paramMap = new HashMap<String, String>();
            paramMap.put("org_code", requestVo.getHospitalCode());
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调base模块, 查询医院信息入参request="
                    + JSON.toJSONString(paramMap));
            Response response1 = BaseService.callUnderlineFromInternal("yyt.base.branchhospital.org.list",
                    JSON.toJSONString(paramMap));
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调base模块, 查询医院信息返回response="
                    + JSONObject.toJSONString(response1));
            if (!"0".equals(response1.getResultCode())) {
                response.setResultCodeAndMessage("3000", "没有org_code对应的机构信息:" + response1.getResultMessage() + "！");
                return response;
            }
            List<Org> orgList = JsonUtils.parseArray(response1.getResult(), Org.class);
            if (CollectionUtils.isEmpty(orgList)) {
                response.setResultCodeAndMessage("3002", "不存在[org_code:" + requestVo.getHospitalCode() + "]对应的医院信息！");
                return response;
            }
            Org org = orgList.get(0);
            dataMap.put("org_id", org.getId());
        }
        logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调base模块, 查询订单接口入参request="
                + JSON.toJSONString(dataMap));
        Response ordResponse = BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.by.order.no.out.get",
                JsonUtils.toJsonString(dataMap));
        logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调base模块, 查询订单接口返回response="
                + JSON.toJSONString(ordResponse));
        if (!"0".equals(ordResponse.getResultCode())) {
            response.setResultCodeAndMessage("3000", "查询订单失败。");
            return response;
        }
        
        OrderExtVo vo = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);
        
        OrderExtVo updateOrderExtVoTmp = new OrderExtVo();
        updateOrderExtVoTmp.setPaymentDealId(requestVo.getPaymentDealId());
        updateOrderExtVoTmp
                .setInsuranceRealAmount(vo.getTotalAmount().intValue() - requestVo.getPayAmount().intValue());
        updateOrderExtVoTmp.setPayRealAmount(requestVo.getPayAmount());
        updateOrderExtVoTmp.setTotalRealAmount(vo.getTotalAmount());
        updateOrderExtVoTmp.setOutOrderNo(requestVo.getOutOrderNo());
        if (requestVo.getPayMode().intValue() == 99) {
            // 99为海鹚支付宝支付，转成对应我们系统的支付宝扫码付23
            updateOrderExtVoTmp.setPayMode((short) 23);
        } else if (requestVo.getPayMode().intValue() == 98) {
            // 98为海鹚微信支付，转成对应我们系统的微信扫码付13
            updateOrderExtVoTmp.setPayMode((short) 13);
        } else {
            if(requestVo.getExPayMode() != null){
                if(requestVo.getExPayMode().intValue() == 212){
                    updateOrderExtVoTmp.setPayMode((short) requestVo.getExPayMode().intValue());
                }
            }else{
                updateOrderExtVoTmp.setPayMode((short) requestVo.getPayMode().intValue());
            }
        }
        updateOrderExtVoTmp.setPayTime(requestVo.getPayTime());
        updateOrderExtVoTmp.setUpdateTime(DateUtils.dateToString(new Date()));
        updateOrderExtVoTmp.setId(vo.getId());
        updateOrderExtVoTmp.setOrderStatusWaitWrite();
        updateOrderExtVoTmp.setPayStatusPayed();
        updateOrderExtVoTmp.setUpdateTime(DateUtils.dateToString(new Date()));
//        updateOrderExtVoTmp.setInsuranceMode(requestVo.getInsuranceMode());
        updateOrderExtVoTmp.setPayAppId(requestVo.getPayeeAppId());
        updateOrderExtVoTmp.setIsPayHandled(1);//支付是否通知并处理0：否，1：是
        vo.setOrderStatusWaitWrite();
        vo.setPayStatusPayed();
        vo.setUpdateTime(DateUtils.dateToString(new Date()));
        logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调base模块, 更新订单状态入参request="
                + JSONObject.toJSONString(updateOrderExtVoTmp));
        // 结算前先保存一次订单信息，防止结算失败导致支付参数丢失。例如支付流水PaymentDealId等
        BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.update",
                JsonUtils.toJsonString(updateOrderExtVoTmp));


        // 判断传入的金额是否有异常(只针对外部订单)
        if(requestVo.getIsFromInner() == null){
            if (vo.getPayAmount().intValue() != requestVo.getPayAmount().intValue()) {
                response.setResultCodeAndMessage("3003",
                        "传入的自费金额和保存的自费金额不一致:[RequestPayAmount:" + requestVo.getPayAmount() + ",SavePayAmount:"
                                + vo.getPayAmount() + ",SaveTotalAmount:" + vo.getTotalAmount() + "]！");
                return response;
            }
        }

        JSONObject extraParamsMap = JsonUtils.parseObject(vo.getExtraParams());
 
        if (requestVo.getIsFromInner() == null || 1 != requestVo.getIsFromInner().intValue()) {
            //  IsFromInner=null为海鹚，IsFromInner=2为云医宝，需要做医保结算
            if (StringUtils.isNotBlank(extraParamsMap.getString("social_security_no")) && vo.getIsInsurance() == 1) {
                // 走医院医保结算逻辑的订单InsuranceMode设为4
                updateOrderExtVoTmp.setInsuranceMode((short) 4);
                vo.setInsuranceMode((short) 4);
                addPaymentJournal(vo, requestVo);
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调base模块, 更新订单状态入参request="
                        + JSONObject.toJSONString(updateOrderExtVoTmp));
                BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.update",
                        JsonUtils.toJsonString(updateOrderExtVoTmp));
                
                String methodName = "yyt.pay.insurance.mz.set";
                Map<String, Object> setMzInsuranceMap = new HashMap<String, Object>();
                setMzInsuranceMap.put("hospital_code", vo.getOrgCode());
                setMzInsuranceMap.put("branch_code", vo.getBranchCode());
                setMzInsuranceMap.put("pat_card_type", vo.getMedicalCardType());
                setMzInsuranceMap.put("pat_card_no", vo.getMedicalCardNo());
                // 写入的订单号为平台的订单号
                setMzInsuranceMap.put("ps_ordnum", vo.getOrderNo());
                setMzInsuranceMap.put("yyt_ord_num", vo.getOrderNo());
                
                setMzInsuranceMap.put("social_security_no", extraParamsMap.get("social_security_no"));
                setMzInsuranceMap.put("pat_card_pwd", extraParamsMap.get("pat_card_pwd"));
                setMzInsuranceMap.put("id_no", vo.getIdCardNo());
                setMzInsuranceMap.put("mz_fee_id", extraParamsMap.get("mz_fee_id"));
                setMzInsuranceMap.put("mz_bill_id", extraParamsMap.get("mz_bill_id"));
                setMzInsuranceMap.put("ss_fee_no", extraParamsMap.get("ss_fee_no"));
                setMzInsuranceMap.put("ss_bill_no", extraParamsMap.get("ss_bill_no"));
                setMzInsuranceMap.put("dept_code", vo.getDeptCode());
                setMzInsuranceMap.put("doctor_code", vo.getDoctorCode());

                setMzInsuranceMap.put("pay_amount", vo.getPayAmount());
                setMzInsuranceMap.put("insurance_amount", vo.getInsuranceAmount());
                setMzInsuranceMap.put("total_amount", vo.getTotalAmount());
                
                Map<String, String> map = new HashMap<String, String>();
                map.put("pat_name", vo.getUserName());
                setMzInsuranceMap.put("extend_params", JSON.toJSONString(map));
                
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调pay-lite模块, 医保结算请求request="
                        + JSON.toJSONString(setMzInsuranceMap));
                Response setMzInsuranceResponse = PayService.callUnderlineFromInternal(methodName,
                        JSON.toJSONString(setMzInsuranceMap));
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调pay-lite模块, 医保结算返回response="
                        + JSON.toJSONString(setMzInsuranceResponse));
                if (!"0".equals(setMzInsuranceResponse.getResultCode())) {
                    // 订单拓展字段添加一个标记记录是否结算异常，异常流程的时候
                    Map<String, String> tmpMap = JsonUtils.parseObject(vo.getExtraParams(), HashMap.class);
                    if(tmpMap == null) {
                        tmpMap = new HashMap<String, String>();
                    }
                    tmpMap.put("is_set_insurance_exception", "true");
                    updateOrderExtVoTmp.setExtraParams(JsonUtils.toJsonString(tmpMap));
                    logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调base模块, 更新订单状态入参request="
                            + JSONObject.toJSONString(updateOrderExtVoTmp));
                    BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.update",
                            JsonUtils.toJsonString(updateOrderExtVoTmp));
                    
                    // 医保结算失败，添加到异常队列处理。
                    addOrderToExceptionList(vo , setMzInsuranceResponse.getResultMessage());
                    
                    response.setResultCodeAndMessage("999",
                            "云医订单号:" + requestVo.getYytOrderNo() + ",外部订单号:" + requestVo.getOutOrderNo() + "做医保结算的时候异常:"
                                    + setMzInsuranceResponse.getResultMessage() + "！");
                    return response;
                }
            } else if(requestVo.getIsFromInner() == null) {
                // 海鹚自费也需要添加流水
                addPaymentJournal(vo, requestVo);
            }else{
                logger.info("订单医保标识：" + vo.getIsInsurance() + " - 医保加密串：" + extraParamsMap.getString("social_security_no"));
            }
        }

        //-------------------------------------写单开始事务----------------------------------------
        /* 写单异常 */
        boolean ackClinicOrderException = false;

        /* 写单是否成功 */
        boolean ackClinicOrderSuccessful = false;

        /* 查询已交费异常 */
        boolean queryListClinicPayException = false;

        /* 查询已交费是否成功（写单异常，但查询缴费记录成功） */
        boolean queryListClinicPaySuccessful = false;

        /* 是否需要发起医保退款 
         * 在以下情况需要发起医保退款的(前提是医保单) :
         * 1.ackClinicOrderSuccessful=false and ackClinicOrderException=false
         * 2.ackClinicOrderException=true and queryListClinicPaySuccessful=false
         */
        boolean isNeedRefundInsurance = false;
        
        /*是否异常单，这种单不能退款，需要人工处理
         * 如果ackClinicOrderException=true and queryListClinicPayException=true
         * 那这笔就是异常单，需要人工介入，查明后再做处理
        */
        boolean isExceptionClinicOrder=false;
        
        // His写单
        PayClinicOrderVo payClinicOrderVo = new PayClinicOrderVo();
        if("gdsdermyy".equals(vo.getOrgCode()) && 1 == vo.getIsInsurance() ){
            payClinicOrderVo.setIsInsurance("1");
        }else if(vo.getInsuranceMode() == null||vo.getInsuranceMode()==0){
            payClinicOrderVo.setIsInsurance("0");
        }else{
            payClinicOrderVo.setIsInsurance("1");
        }
        payClinicOrderVo.setPayTime(requestVo.getPayTime());
        payClinicOrderVo.setPayMode(ObjectParser.toString(requestVo.getPayMode()));
        payClinicOrderVo.setAgtOrdNum(requestVo.getPaymentDealId());
        payClinicOrderVo.setAgtCode("");
        payClinicOrderVo.setYytOrdNum(vo.getOrderNo());
        payClinicOrderVo.setTotalAmount(ObjectParser.toString(vo.getTotalAmount()));
        payClinicOrderVo.setPayAmount(ObjectParser.toString(vo.getPayAmount()));
        payClinicOrderVo.setDoctorCode(vo.getDoctorCode());
        payClinicOrderVo.setDeptCode(vo.getDeptCode());
        payClinicOrderVo.setMzBillId(ObjectParser.toString(extraParamsMap.get("mz_bill_id")));
        payClinicOrderVo.setMzFeeId(ObjectParser.toString(extraParamsMap.get("mz_fee_id")));
        payClinicOrderVo.setHospitalCode(vo.getOrgCode());
        payClinicOrderVo.setBranchCode(vo.getBranchCode());
        Map<String, Object> extMap = new HashMap<String, Object>();
        extMap.put("recipe_type", extraParamsMap.get("recipe_type"));
        extMap.put("recipe_id", extraParamsMap.get("recipe_id"));
        extMap.put("ss_fee_no", extraParamsMap.get("ss_fee_no"));
        extMap.put("ss_bill_no", extraParamsMap.get("ss_bill_no"));
        extMap.put("account_amount", vo.getAccountAmount());
        extMap.put("medicare_amount", vo.getMedicareAmount());
        extMap.put("insurance_amount", vo.getInsuranceAmount());
        extMap.put("paid_amount", extraParamsMap.get("paid_amount"));
        extMap.put("id_card_no", vo.getIdCardNo());
        extMap.put("user_name", vo.getUserName());

        if (requestVo.getIsFromInner() != null) {
            extMap.put("is_from_inner", requestVo.getIsFromInner().intValue());
        }
        String isd = extraParamsMap.getString("industry_sepc_detail");
        if(StringUtils.isNotBlank(isd)) {
            extMap.put("industry_sepc_detail", isd);
        } else {
            extMap.put("industry_sepc_detail", "");
        }
        extMap.put("time", vo.getCreatedTime());
        extMap.put("his_ord_num", vo.getHisOrderNo());//佛一写单增加参数
        extMap.put("pat_card_no", vo.getMedicalCardNo());
        extMap.put("pat_card_type", vo.getMedicalCardType());
        if(vo.getOrgCode().indexOf("szsykyy") >=0 && vo.getPlatformOrgAppCode().equals("yyt48fe49dbe6eb1cee")){
            extraParamsMap.put("channel","1");
        }else if(vo.getOrgCode().indexOf("szsykyy") >=0 && vo.getPlatformOrgAppCode().equals("yytcda5b2de00d8717c")){
            extraParamsMap.put("channel","2");
        }
        payClinicOrderVo.setExtendParams(JsonUtils.toJsonString(extMap));
 
        // 是否需要加入异常队列，注：失败也加入异常队列进行退费
        PayClinicOrderVoResponse payClinicOrderVoResponse = null;
        try {
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调hisiface模块, 门诊缴费订单支付接口入参request="
                    + JSONObject.toJSONString(payClinicOrderVo));
            ResCommon<PayClinicOrderVoResponse> payClinicOrderResponse = HisifaceService.getHisifaceClient()
                    .payClinicOrder(payClinicOrderVo);
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调hisiface模块, 门诊缴费订单支付接口返回response="
                    + JSONObject.toJSONString(payClinicOrderResponse));
            if ("0".equals(payClinicOrderResponse.getResultCode())) {
                ackClinicOrderSuccessful = true;
                payClinicOrderVoResponse = JsonUtils.parseObject(payClinicOrderResponse.getResult(),
                        PayClinicOrderVoResponse.class);
//            } else if ("4001".equals(payClinicOrderResponse.getResultCode())) {
//                // 明确失败，目前写单只有成功和异常两种情况。
//                ackClinicOrderSuccessful = false;
//                addOrderToExceptionList(vo);
            } else {
                // 异常
                addOrderToExceptionList(vo , payClinicOrderResponse.getResultMessage());
                OrderExtVo updateOrderExtVo = new OrderExtVo();
                updateOrderExtVo.setId(vo.getId());
                updateOrderExtVo.setOrderStatusException();//写单异常
                updateOrderExtVo.setPayStatusPayed();//支付成功
                updateOrderExtVo.setUpdateTime(DateUtils.dateToString(new Date()));
                updateOrderExtVo.setInsuranceMode(requestVo.getInsuranceMode());
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 写单异常, 调base模块, 更新订单状态入参request="
                        + JSONObject.toJSONString(updateOrderExtVo));
                BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.update",
                        JsonUtils.toJsonString(updateOrderExtVo));
                
                response.setResultCodeAndMessage("999",
                        "云医订单号:" + requestVo.getYytOrderNo() + ",外部订单号:" + requestVo.getOutOrderNo() + "写单超时，请稍后再试!");
                return response;
            }
        } catch (Exception ex) {
            logger.info("门诊支付写单外部接口, 订单号:" + requestVo.getYytOrderNo() + ", 外部订单号:" + requestVo.getOutOrderNo()
                    + "写单异常，需要查询HIS是否写单成功!");
            logger.error("error", ex);
            ackClinicOrderException = true;
            addOrderToExceptionList(vo , "门诊支付写单外部接口, 订单号:" + requestVo.getYytOrderNo() + ", 外部订单号:" + requestVo.getOutOrderNo() + "写单异常，需要查询HIS是否写单成功!");
        }

        // 如果出现写单异常，则发起已缴费记录查询
        if (ackClinicOrderException) {
            PayVo payvo = new PayVo();
            payvo.setHospitalCode(vo.getOrgCode());
            payvo.setBranchCode(vo.getBranchCode());
            payvo.setPatCardType(ObjectParser.toString(vo.getMedicalCardType()));
            payvo.setPatCardNo(vo.getMedicalCardNo());
            payvo.setPayMode(ObjectParser.toString(requestVo.getPayMode()));
            payvo.setYytOrdNum(vo.getOrderNo());
            payvo.setSessionId(sessionId);
            Map<String, Object> extendMap = new HashMap<String, Object>();
            extendMap.put("his_ord_num", vo.getHisOrderNo());//佛一门诊已缴费记录查询增加参数
            payvo.setExtendParams(JsonUtils.toJsonString(extendMap));
            Calendar calendar = Calendar.getInstance(); 
            calendar.add(Calendar.MONTH, -1);
            payvo.setBeginDate(DateUtils.getDateStr(calendar.getTime()));
            payvo.setEndDate(DateUtils.getDateStr(new Date()));
            try {
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 写单异常, 调hisiface模块, 门诊已缴费记录查询接口入参request="
                        + JSONObject.toJSONString(payvo));
                ResCommon<List<PayVoResponse>> payResponse = HisifaceService.getHisifaceClient().listClinicPay(payvo);
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo()
                        + ", 写单异常, 调hisiface模块, 门诊已缴费记录查询接口返回response=" + JSON.toJSONString(payResponse));
                if ("0".equals(payResponse.getResultCode())) {
                    queryListClinicPaySuccessful=true;
                } else{
                    queryListClinicPaySuccessful=false;
                }
            } catch (Exception ex) {
                logger.info("门诊支付写单外部接口, 订单号:" + requestVo.getYytOrderNo() + ", 外部订单号:" + requestVo.getOutOrderNo()
                        + "查单失败, 异常单, 人工介入查询！");
                logger.error("error", ex);
                queryListClinicPayException = true;
            }
            
            //如果查单正常，说明写单是成功的
            if(queryListClinicPaySuccessful){
                ackClinicOrderSuccessful=true;
            }
        }        
        //-------------------------------------写单事务结束----------------------------------------
        
        try {
            //异常单
            if(ackClinicOrderException&& queryListClinicPayException){
                isExceptionClinicOrder=true;
            }
            
            if(isExceptionClinicOrder){
                OrderExtVo updateOrderExtVo = new OrderExtVo();
                updateOrderExtVo.setId(vo.getId());
                updateOrderExtVo.setOrderStatusException();//写单异常
//                updateOrderExtVo.setPayStatusAccess();//支付中
                updateOrderExtVo.setUpdateTime(DateUtils.dateToString(new Date()));
                updateOrderExtVo.setInsuranceMode(requestVo.getInsuranceMode());
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 写单异常, 调base模块, 更新订单状态入参request="
                        + JSONObject.toJSONString(updateOrderExtVo));
                BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.update",
                        JsonUtils.toJsonString(updateOrderExtVo));
                
                response.setResultCodeAndMessage("3004",
                        "云医订单号:" + requestVo.getYytOrderNo() + ",外部订单号:" + requestVo.getOutOrderNo() + "写单异常，人工介入是否可以退款，请勿自动退款!");
                return response;
            }
            
            //-------------------医保退款逻辑-----------------------------
            //判断医保单是否需要执行医保退款
            if (vo.getInsuranceMode() != null) {// 如果是医保单
                if((ackClinicOrderSuccessful==false &&ackClinicOrderException==false)||
                        (ackClinicOrderException==true && queryListClinicPaySuccessful==false)){
                    isNeedRefundInsurance=true;
                }
            }
            //执行医保退款
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 是否需要医保退费=" + isNeedRefundInsurance);
            if(isNeedRefundInsurance){
                refundInsurance(vo);
            }
            //-------------------医保退款结束------------------------------
            
            //如果写单失败
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 写单是否成功=" + ackClinicOrderSuccessful);
            if(!ackClinicOrderSuccessful){
                OrderExtVo updateOrderExtVo = new OrderExtVo();
                updateOrderExtVo.setId(vo.getId());
                updateOrderExtVo.setOrderStatusException();//写单异常
                updateOrderExtVo.setPayStatusPayed();//已支付
                updateOrderExtVo.setUpdateTime(DateUtils.dateToString(new Date()));
                updateOrderExtVo.setInsuranceMode(requestVo.getInsuranceMode());
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 写单异常, 调base模块, 更新订单状态入参request="
                        + JSONObject.toJSONString(updateOrderExtVo));
                BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.update",
                        JsonUtils.toJsonString(updateOrderExtVo));
                response.setResultCodeAndMessage("3005",
                        "云医订单号:" + requestVo.getYytOrderNo() + ",外部订单号:" + requestVo.getOutOrderNo() + "写单失败!");
                return response;
            }
            
            /**
             * 写单成功：
             * 1.更新门诊订单的状态
             * 2.插入支付流水
             */
            
            OrderExtVo updateOrderExtVo = new OrderExtVo();
            updateOrderExtVo.setPaymentDealId(requestVo.getPaymentDealId());
            updateOrderExtVo
                    .setInsuranceRealAmount(vo.getTotalAmount().intValue() - requestVo.getPayAmount().intValue());
            updateOrderExtVo.setPayRealAmount(requestVo.getPayAmount());
            updateOrderExtVo.setTotalRealAmount(vo.getTotalAmount());
            updateOrderExtVo.setHisOrderNo(payClinicOrderVoResponse.getHisOrdNum());
            updateOrderExtVo.setHisMessage(payClinicOrderVoResponse.getHisMessage());
            updateOrderExtVo.setBarcode(payClinicOrderVoResponse.getBarCode());
            updateOrderExtVo.setReceiptNum(payClinicOrderVoResponse.getReceiptNum());
            updateOrderExtVo.setOutOrderNo(requestVo.getOutOrderNo());
            if (requestVo.getPayMode().intValue() == 99) {
                updateOrderExtVo.setPayMode((short) 23);
            } else if (requestVo.getPayMode().intValue() == 99) {
                updateOrderExtVo.setPayMode((short) 13);
            } else {
                if(requestVo.getExPayMode() != null){
                    if(requestVo.getExPayMode().intValue() == 212){
                        updateOrderExtVo.setPayMode((short) requestVo.getExPayMode().intValue());
                    }
                }else{
                    updateOrderExtVo.setPayMode((short) requestVo.getPayMode().intValue());
                }
            }
            updateOrderExtVo.setPayTime(requestVo.getPayTime());
            updateOrderExtVo.setUpdateTime(DateUtils.dateToString(new Date()));
            updateOrderExtVo.setId(vo.getId());
            updateOrderExtVo.setOrderStatusSuccess();
            updateOrderExtVo.setPayStatusPayed();
            updateOrderExtVo.setUpdateTime(DateUtils.dateToString(new Date()));
            updateOrderExtVo.setInsuranceMode(requestVo.getInsuranceMode());
            updateOrderExtVo.setPayAppId(requestVo.getPayeeAppId());
            vo.setOrderStatusSuccess();
            vo.setPayStatusPayed();
            vo.setUpdateTime(DateUtils.dateToString(new Date()));
            vo.setHisOrderNo(payClinicOrderVoResponse.getHisOrdNum());
            vo.setHisMessage(payClinicOrderVoResponse.getHisMessage());
            vo.setBarcode(payClinicOrderVoResponse.getBarCode());
            vo.setReceiptNum(payClinicOrderVoResponse.getReceiptNum());
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 写单成功, 调base模块, 更新订单状态入参request="
                    + JSONObject.toJSONString(updateOrderExtVo));
            BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.update",
                    JsonUtils.toJsonString(updateOrderExtVo));
            
            PaymentJournalVo tmp = new PaymentJournalVo();
            tmp.setOrderNo(vo.getOrderNo());
            tmp.setPayStatus((short) 1);
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调用pay-lite模块, 查询支付流水接口入参request="
                    + JSON.toJSONString(tmp));
            Response findPaymentJournalResponse = PayService.callUnderlineFromInternal("yyt.pay.payment.journal.find",
                    JsonUtils.toJsonString(tmp));
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调用pay-lite模块, 查询支付流水接口返回response="
                    + JSON.toJSONString(findPaymentJournalResponse));
            if ("0".equals(findPaymentJournalResponse.getResultCode())) {
                List<PaymentJournalVo> pjs = JsonUtils.parseArray(findPaymentJournalResponse.getResult(),
                        PaymentJournalVo.class);
                PaymentJournalVo psv = pjs.get(0);
                psv.setHisOrderNo(payClinicOrderVoResponse.getHisOrdNum());
                psv.setInsuranceMode(requestVo.getInsuranceMode());
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo()
                        + ", 如果流水已存在则更新流水, 调用pay-lite模块, 更新支付流水接口入参request=" + JSON.toJSONString(psv));
                PayService.callUnderlineFromInternal("yyt.pay.payment.journal.update", JsonUtils.toJsonString(psv));
            }

            //获取手机号
            String patMobile = "";
            String openId = (StringUtils.isNotBlank(vo.getOpenId()) ? vo.getOpenId() : StringUtils.isNotBlank(requestVo.getUserId()) ? requestVo.getUserId() : requestVo.getOpenId());
            Map<String, String> map = new HashMap<String, String>();
            map.put("open_id" , openId);
            Response personalResponse = BaseService.callHumpFromInternal("yyt.base.personalUser.mobile.by.openid.get", JsonUtils.toJsonString(map));
            if(Response.SUCCESS_CODE.equals(personalResponse.getResultCode())){
                PersonalUser personalUser = JsonUtils.parseObject(personalResponse.getResult(), PersonalUser.class);
                patMobile = personalUser.getMobile();
                logger.info("用户：" + vo.getUserName() +", 最终获取推送消息授权用户手机号：" + patMobile);
            }

            String hisMessage = "";
            if(StringUtils.isNotBlank(vo.getHisMessage())){
                hisMessage = vo.getHisMessage();
            }else{
                hisMessage = "暂无";
            }


            //海慈或手机号为null不发短消息
            String msgContent = "";
            if(requestVo.getIsFromInner() != null && StringUtils.isNotBlank(patMobile)){
                msgContent = "{\\\"receipt_num\\\":\\\""+ vo.getReceiptNum() +"\\\",\\\"his_message\\\":\\\""+ hisMessage +"\\\",\\\"sms_type\\\":\\\"51\\\",\\\"sms_mobile\\\":\\\""+ patMobile +"\\\"}";
            }

            //消息推送
            String url=yaml.getProperty("order.clinic.url")+"order_no="+vo.getOrderNo()+"&app_code="+vo.getPlatformOrgAppCode()+"&open_id="+vo.getOpenId()+"&app_id="+vo.getPayAppId();
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() +"消息跳转URL->"+url);
            try{
                String method = "yyt.message.msg.template.send";
                String messageContent = "{\"user_type\":\"2\",\"order_no\":\"" + vo.getOrderNo()
                        + "\",\"org_app_code\":\"" + vo.getPlatformOrgAppCode()+"\",\"url\":\""+url
                        + "\",\"org_code\":\"" + vo.getOrgCode()
                        + "\",\"sms_msg_content\":\"" + msgContent
                        + "\",\"platform_type\":\"";

                if (requestVo.getPayMode().intValue() == 12 || requestVo.getPayMode().intValue() == 16) {
                    messageContent += "1";
                } else {
                    messageContent += "2";
                }
                messageContent += "\",\"hospital_code\":\"" + vo.getOrgCode() + "\",\"to_user\":\""
                        + (StringUtils.isNotBlank(vo.getOpenId()) ? vo.getOpenId()
                                : StringUtils.isNotBlank(requestVo.getUserId()) ? requestVo.getUserId()
                                        : requestVo.getOpenId())
                        + "\",\"template_code\":\"";
                if (requestVo.getPayMode().intValue() == 12 || requestVo.getPayMode().intValue() == 16) {
                    messageContent += "22001";
                    messageContent+="\",\"msg_content\":\"{"
                            +"\\\"first\\\": \\\"你完成了一笔门诊缴费。\\\",\\\"keynote1\\\": \\\""
                            + vo.getUserName()
                            + "\\\",\\\"his_message\\\":\\\"" + vo.getHisMessage()
                            + "\\\",\\\"receipt_num\\\":\\\"" + vo.getReceiptNum()
                            + "\\\",\\\"keynote2\\\": \\\""
                            + vo.getOrderNo()
                            + "\\\",\\\"keynote3\\\": \\\""
                            + ObjectParser.toDouble(vo.getTotalAmount()) / 100
                            + "(元)\\\",\\\"keynote4\\\":\\\""
                            + (vo.getDoctorName() == null?"":vo.getDoctorName())
                            + "\\\",\\\"keynote5\\\": \\\""
                            + (vo.getDeptName() ==null?"":vo.getDeptName())
                            + "\\\",\\\"keynote6\\\":\\\""
                            + vo.getOrgName()
                            + "\\\",\\\"keynote7\\\": \\\""
                            + requestVo.getPayTime()
                            + "\\\",\\\"remark\\\": ";
                    		//TODO:加入河源硬编码，方便快速上线，以后需要按规则去配置医院的节点值，或者配置单独的配置河源模板出去
                    		if(!"hysrmyy".equals(vo.getOrgCode())){
                				messageContent+="\\\"取药地址:" + (StringUtils.isNotBlank(payClinicOrderVoResponse.getHisMessage())?payClinicOrderVoResponse.getHisMessage():"" ) +"\\\\n";
                                messageContent+= "发票号:" + (StringUtils.isNotBlank(payClinicOrderVoResponse.getReceiptNum())?payClinicOrderVoResponse.getReceiptNum():"") + "\\\"}\"}";
                			}else{
                                messageContent+="\\\"请需要发票的患者在3个月内到收费窗口补打发票，超过时间则不能补打发票。\\\\n";
                                messageContent+= "\\\"}\"}";
                			}

                } else {
                    messageContent += "22001";
                    messageContent+="\",\"msg_content\":\"{\\\"first\\\": \\\"你完成了一笔门诊缴费。\\\",\\\"keyword1\\\": \\\""
                            + vo.getUserName()
                            + "\\\",\\\"his_message\\\":\\\"" + vo.getHisMessage()
                            + "\\\",\\\"receipt_num\\\":\\\"" + vo.getReceiptNum()
                            + "\\\",\\\"keyword2\\\": \\\""
                            + vo.getOrderNo()
                            + "\\\",\\\"keyword3\\\": \\\""
                            + ObjectParser.toDouble(vo.getTotalAmount()) / 100
                            + "(元)\\\",\\\"keyword4\\\":\\\""
                            + (vo.getDoctorName() == null?"":vo.getDoctorName())
                            + "\\\",\\\"keyword5\\\": \\\""
                            + vo.getDeptName()
                            + "\\\",\\\"keyword6\\\":\\\""
                            + vo.getOrgName()
                            + "\\\",\\\"keyword7\\\": \\\""
                            + requestVo.getPayTime()
                            + "\\\",\\\"remark\\\": ";
		                  	//TODO:加入河源硬编码，方便快速上线，以后需要按规则去配置医院的节点值，或者配置单独的配置河源模板出去
		            		if(!"hysrmyy".equals(vo.getOrgCode())){
		        				messageContent+="\\\"取药地址:" + (StringUtils.isNotBlank(payClinicOrderVoResponse.getHisMessage())?payClinicOrderVoResponse.getHisMessage():"") + "\\\\n";
                                messageContent+= "发票号:" + (StringUtils.isNotBlank(payClinicOrderVoResponse.getReceiptNum())?payClinicOrderVoResponse.getReceiptNum():"") + "\\\"}\"}";
		        			}
		            		else{
                                messageContent+="\\\"请需要发票的患者在3个月内到收费窗口补打发票，超过时间则不能补打发票。\\\\n";
                                messageContent+= "\\\"}\"}";
                			}
                }

                
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调用message模块, 消息推送接口入参request="
                        + messageContent);
                Response messageResponse = MessageService.callHumpFromInternal(method, messageContent);
                logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 调用message模块, 消息推送接口返回response="
                        + JSON.toJSONString(messageResponse));
                Map<String,Object> getSendAppMsgTemp=new HashMap<>();
                getSendAppMsgTemp.put("platform_org_app_code",vo.getPlatformOrgAppCode());
                getSendAppMsgTemp.put("platform_type",String.valueOf(Integer.valueOf(vo.getPayMode())/10%10));
                getSendAppMsgTemp.put("platform_template_code",TEMPLATECODE);
                getSendAppMsgTemp.put("push_type",3);
                getSendAppMsgTemp.put("data_source","1");
                logger.info("门诊支付写单外部接口,获取应用消息配置, 订单号" + vo.getOrderNo() + ", 调用message模块, request={}",
                        JSON.toJSONString(getSendAppMsgTemp));
                Response msgAppTemplateBone = MessageService.callUnderlineFromInternal("yyt.message.msg.App.template.bone.get", JsonUtils.toJsonString(getSendAppMsgTemp));
                logger.info("门诊支付写单外部接口,获取应用消息配置, 订单号" + vo.getOrderNo() + ", 调用message模块, response={}",
                        JSON.toJSONString(msgAppTemplateBone));
                if("0".equals(msgAppTemplateBone.getResultCode())){
                    List<OrgAppTemplateVo> orgAppTemplateVoList = JsonUtils.parseArray(msgAppTemplateBone.getResult(), OrgAppTemplateVo.class);
                    if(!CollectionUtils.isEmpty(orgAppTemplateVoList)&&orgAppTemplateVoList.size()>0){
                        try {
                            for (OrgAppTemplateVo orgAppTemplateVo : orgAppTemplateVoList) {
                                if (StringUtils.isNotBlank(orgAppTemplateVo.getPushDept())) {
                                    Map pushDeptMap = JSONObject.parseObject(orgAppTemplateVo.getPushDept(), Map.class);
                                    if (pushDeptMap.containsKey(vo.getOrgCode())) {
                                        List<String> pushDeptList = Arrays.asList(pushDeptMap.get(vo.getOrgCode()).toString().split(";"));
                                        if (pushDeptList.contains(vo.getDeptCode())) {
                                            //推送图文消息
                                            sendIMGMessage(vo, orgAppTemplateVo);
                                        }
                                    }
                                }
                            }
                        }catch (Exception  e){
                            logger.error("门诊支付写单外部接口,获取应用消息配置失败:", e);
                        }
                    }
                }

                if("yytc06514ff54dbe32d".equals(vo.getPlatformOrgAppCode())){
                    //云医通插入消息记录
                    Map<String,Object> historyMap = new HashedMap();
                    historyMap.put("id",PKGenerator.generateId());
                    historyMap.put("org_id", vo.getOrgId());
                    historyMap.put("org_name",vo.getOrgName());
                    historyMap.put("org_code",vo.getOrgCode());
                    historyMap.put("user_id",vo.getUserId());
                    historyMap.put("user_name",vo.getUserName());
//            map.put("library_template_code",msgCenter.getTemplateId());
                    historyMap.put("msg_title","门诊缴费成功通知");
                    historyMap.put("is_read",1);
//            map.put("msg_content",msgCenter.getMsgContent());

                    Map<String,Object> contentMap = new HashedMap();
                    List<Map<String,String>> msgTemplateContents = new ArrayList<>();
                    Map<String,String> firstMap = new HashedMap();
                    firstMap.put("keyword","first");
                    firstMap.put("note","");
                    firstMap.put("value","您完成了一笔门诊缴费。");
                    msgTemplateContents.add(firstMap);

                    Map<String,String> k1Map = new HashedMap();
                    k1Map.put("keyword","姓名");
                    k1Map.put("note","");
                    k1Map.put("value",vo.getUserName());
                    msgTemplateContents.add(k1Map);

                    Map<String,String> k2Map = new HashedMap();
                    k2Map.put("keyword","医院");
                    k2Map.put("note","");
                    k2Map.put("value",vo.getOrgName());
                    msgTemplateContents.add(k2Map);

                    Map<String,String> k3Map = new HashedMap();
                    k3Map.put("keyword","科室");
                    k3Map.put("note","");
                    k3Map.put("value",vo.getDeptName());
                    msgTemplateContents.add(k3Map);

                    Map<String,String> k4Map = new HashedMap();
                    k4Map.put("keyword","医生");
                    k4Map.put("note","");
                    k4Map.put("value",vo.getDoctorName());
                    msgTemplateContents.add(k4Map);

                    Map<String,String> k5Map = new HashedMap();
                    k5Map.put("keyword","订单号");
                    k5Map.put("note","");
                    k5Map.put("value",vo.getOrderNo());
                    msgTemplateContents.add(k5Map);

                    if(!"hysrmyy".equals(vo.getOrgCode())){
                        Map<String,String> k6Map = new HashedMap();
                        k6Map.put("keyword","取药地址");
                        k6Map.put("value",payClinicOrderVoResponse.getHisMessage());
                        msgTemplateContents.add(k6Map);

                        Map<String,String> k7Map = new HashedMap();
                        k7Map.put("keyword","发票号");
                        k7Map.put("value",payClinicOrderVoResponse.getReceiptNum());
                        msgTemplateContents.add(k7Map);
                    }

                    contentMap.put("msgTemplateContents", msgTemplateContents);

                    List<Map<String,String>> msgTemplateFunctions = new ArrayList<>();
                    Map<String,String> funcMap = new HashedMap();
                    funcMap.put("functionCode","location='" +url + "'" );
                    funcMap.put("functionName","点击查看详情");
                    msgTemplateFunctions.add(funcMap);

                    contentMap.put("msgTemplateFunctions",msgTemplateFunctions);
                    historyMap.put("msg_content",JsonUtils.toJsonString(contentMap));
//            map.put("icon_name",msgCenter.getIconName());
//            map.put("icon_path",msgCenter.getIconPath());
                    historyMap.put("created_time",DateUtils.dateToString(new Date()));

                    messageResponse = MessageService.callHumpFromInternal("yyt.message.messagehistory.add",JsonUtils.toJsonString(historyMap));
                    logger.info("订单号" + vo.getOrderNo() + ", 调用message模块,yyt.message.messagehistory.add request={}，response={}",
                            JsonUtils.toJsonString(historyMap),JsonUtils.toJsonString(messageResponse));

                }
                //推广端挂号成功发送短信
                if("yytc773c9f311c94c6e".equals(vo.getPlatformOrgAppCode())){
                    Map<String,Object> smsMap = new HashedMap();
                    smsMap.put("org_code",vo.getOrgCode());
                    smsMap.put("to_user",vo.getUserMobile());
                    smsMap.put("template_code","sms_clinic_001");
                    smsMap.put("platform_org_app_code","yytc773c9f311c94c6e");
                    Map<String,String> contentMap = JsonUtils.parseObject(JsonUtils.toJsonString(vo),Map.class);
                    contentMap.putAll(JsonUtils.parseObject(vo.getExtraParams(),Map.class));
                    contentMap.put("pay_time",requestVo.getPayTime());
                    smsMap.put("msg_content",contentMap);

                    messageResponse = MessageService.callHumpFromInternal("yyt.message.msg.sms.send",JsonUtils.toJsonString(smsMap));
                    logger.info("订单号" + vo.getOrderNo() + ", 调用message模块,yyt.message.msg.sms.send request={}，response={}",
                            JsonUtils.toJsonString(smsMap),JsonUtils.toJsonString(messageResponse));
                }

            }catch(Exception e){
                logger.error("门诊支付写单外部接口, 门诊支付成功后消息推送失败:", e);
            }

            //TODO：自动绑卡

            response.setResultCodeAndMessage("0","处理成功");
            response.setResult(JsonUtils.toJsonString(payClinicOrderVoResponse));
            logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 方法出参response="
                    + JSONObject.toJSONString(response));
        } catch(Exception e) {
            logger.error("门诊支付写单异常!" , e);
            response.setResultCodeAndMessage("3007", "云医订单号:" + requestVo.getYytOrderNo() + ",外部订单号:"
                    + requestVo.getOutOrderNo() + "写单异常，人工介入是否可以退款，请勿自动退款!");
            return response;
        }

        try {
            if (requestVo.getIsFromInner() == null) {
                if (vo.getPayAmount().intValue() == 0) {
                    String url = "";
                    if ("true".equals(TestFlag.TEST_FLAG)) {
                        url = "http://uapi.gzhc365.com/openapi/HttpServices";
                    } else {
                        url = "http://mp.gzhc365.com/openapi/HttpServices";
                    }
                    String dateTime = DateUtils.dateToString(new Date());
                    // String key="51C3B977EE8C1ADDA09ECE608EF726F8";
                    String key = "51C3B977EE8C1ADDA09ECE608EF726F8";
                    String str = dateTime + key;
                    String password = MD5Util.string2MD5(str).toUpperCase();
                    String partnerId = "BJDXSZYY";

                    StringBuffer sb = new StringBuffer();
                    sb.append("<request>");
                    sb.append("<serviceCode>").append("OrderConfirmAllMed").append("</serviceCode>");
                    sb.append("<partnerId>").append(vo.getOrgCode().toUpperCase()).append("</partnerId>");
                    sb.append("<timestamp>").append(dateTime).append("</timestamp>");
                    sb.append("<password>").append(key).append("</password>");
                    sb.append("<hospital_code>").append(vo.getOrgCode()).append("</hospital_code>");
                    sb.append("<branch_code>").append(vo.getBranchCode()).append("</branch_code>");
                    sb.append("<yyt_order_no>").append(vo.getOrderNo()).append("</yyt_order_no>");
                    sb.append("<pay_status>").append(vo.getPayStatus().intValue() == 3 ? "1" : "2")
                            .append("</pay_status>");
                    sb.append("<receipt_num>").append(vo.getReceiptNum()).append("</receipt_num>");
                    sb.append("<his_message>").append(vo.getHisMessage()).append("</his_message>");
                    sb.append("</request>");
                    logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 通知海鹚接口入参request=" + sb.toString());
                    String result = HttpsUtil.doPost(url, sb.toString());
                    logger.info("门诊支付写单外部接口, 订单号" + requestVo.getYytOrderNo() + ", 通知海鹚接口返回response=" + result);
                }
            }
        } catch (Exception e) {
            logger.error("门诊支付写单外部接口 error", e);
        }
        return response;
    }

    public void sendIMGMessage(final OrderExtVo order,final OrgAppTemplateVo orgAppTemplateVo) {
        logger.info("门诊支付写单->发送推送Bone图文消息Start");
        try {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(60000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Map<String,String> sendDataMap=new HashedMap();
                    sendDataMap.put("user_type","2");
                    sendDataMap.put("to_user", order.getOpenId());
                    if ("1".equals(String.valueOf(Integer.valueOf(order.getPayMode())/10%10))) {
                        sendDataMap.put("platform_type","1");
                    }else if("2".equals(String.valueOf(Integer.valueOf(order.getPayMode())/10%10))){
                        sendDataMap.put("platform_type","2");
                    }
                    sendDataMap.put("org_app_code",order.getPlatformOrgAppCode());
                    sendDataMap.put("org_code",orgAppTemplateVo.getDevOrgCode());
                    //根据模板code查询图片信息
                    ImageTemplateVo imageTemplateVo = new ImageTemplateVo();
                    imageTemplateVo.setTemplateCode(orgAppTemplateVo.getLibraryTemplateCode());
                    logger.info("门诊支付写单->发送推送图文消息->根据模板code查询图片明细request->{}",JSON.toJSONString(imageTemplateVo));
                    Response response = BaseService.callHumpFromInternal("yyt.base.image.template.by.code.get", JsonUtils.toJsonString(imageTemplateVo));
                    logger.info("门诊支付写单->发送推送图文消息->根据模板code查询图片明细response->{}",JSON.toJSONString(response));
                    if("0".equals(response.getResultCode())){
                        List<ImageTemplateListVo> images = JsonUtils.parseArray(response.getResult(), ImageTemplateListVo.class);
                        ImageTemplateListVo imageTemplateList = null;
                        for (ImageTemplateListVo image : images) {
                            if(IMG_TEMPLATECODE.equals(image.getImageTemplateCode())){
                                imageTemplateList = image;
                                break;
                            }
                        }
                        //组装点击链接
                        if(imageTemplateList != null){
                            logger.info("imageTemplateList:" +JSON.toJSONString(imageTemplateList));
                            sendDataMap.put("image_url", imageTemplateList.getImageUrl());
                            sendDataMap.put("title", imageTemplateList.getImageTitle());
                            sendDataMap.put("url", imageTemplateList.getActionUrl());
                            sendDataMap.put("action_name", imageTemplateList.getActionName());
                            sendDataMap.put("desc", imageTemplateList.getImageContent());
                            logger.info("门诊支付写单->发送推送图文消息->request->{}",JSON.toJSON(sendDataMap));
                            Response responseMsg=MessageService.callHumpFromInternal("yyt.message.msg.image.send", JsonUtils.toJsonString(sendDataMap));
                            logger.info("门诊支付写单->发送推送图文消息->response->{}",JSON.toJSON(responseMsg));
                            if("ok".equals(responseMsg.getResult())){
                                Map<String,String> requestMap=new HashMap<>();
                                requestMap.put("id",orgAppTemplateVo.getId());
                                requestMap.put("add_type","1");
                                logger.info("门诊支付写单->发送推送图文消息推送增加次数->request->{}",JSON.toJSON(requestMap));
                                Response responseTemCout = MessageService.callUnderlineFromInternal("yyt.message.msg.app.template.count.add", JsonUtils.toJsonString(requestMap));
                                logger.info("门诊支付写单->发送推送图文消息推送增加次数->response->{}",JSON.toJSON(responseTemCout));
                            }
                        }else{
                            logger.info("无法获取图片22012模板配置参数.. templateCode：" + imageTemplateVo.getTemplateCode());
                        }
                    }else{
                        logger.info("无法获取图片模板22012配置参数.. templateCode：" + imageTemplateVo.getTemplateCode());
                    }
                }
            }).start();
        } catch (Exception e) {
            logger.error("门诊支付写单->发送推送Bone图文消息异常", e);
        }
    }
    
    private void refundInsurance(OrderExtVo vo ){
        String methodName = "yyt.pay.insurance.mz.refund";
        Map<String, Object> refundMzInsuranceMap = new HashMap<String, Object>();
        refundMzInsuranceMap.put("hospital_code", vo.getOrgCode());
        refundMzInsuranceMap.put("branch_code", vo.getBranchCode());
        refundMzInsuranceMap.put("pat_card_type", vo.getMedicalCardType());
        refundMzInsuranceMap.put("pat_card_no", vo.getMedicalCardNo());
        // 写入的订单号为平台的订单号
        JSONObject extraParamsMap = JsonUtils.parseObject(vo.getExtraParams());
        refundMzInsuranceMap.put("ps_ordnum", vo.getOrderNo());
        refundMzInsuranceMap.put("yyt_ord_num", vo.getOrderNo());
        
        refundMzInsuranceMap.put("mz_fee_id", extraParamsMap.get("mz_fee_id"));
        refundMzInsuranceMap.put("mz_bill_id", extraParamsMap.get("mz_bill_id"));
        refundMzInsuranceMap.put("ss_fee_no", extraParamsMap.get("ss_fee_no"));
        refundMzInsuranceMap.put("ss_bill_no", extraParamsMap.get("ss_bill_no"));
        refundMzInsuranceMap.put("cancel_serial_no", extraParamsMap.get("cancel_serial_no"));
        refundMzInsuranceMap.put("cancel_bill_no", extraParamsMap.get("cancel_bill_no"));
        
        refundMzInsuranceMap.put("dept_code", vo.getDeptCode());
        refundMzInsuranceMap.put("doctor_code", vo.getDoctorCode());
        
        logger.info("医保退款, 订单号" + vo.getOrderNo() + ", 请求入参request=" + JSON.toJSONString(refundMzInsuranceMap));
        Response refundMzInsuranceResponse = PayService.callUnderlineFromInternal(methodName,
                JSON.toJSONString(refundMzInsuranceMap));
        logger.info("医保退款, 订单号" + vo.getOrderNo() + ", 请求返回response=" + JSON.toJSONString(refundMzInsuranceResponse));
    }
    
    private void addPaymentJournal(OrderExtVo vo, AckPayOrderOutVoRequest requestVo) {
        PaymentJournalVo tmp = new PaymentJournalVo();
        tmp.setOrderNo(vo.getOrderNo());
        tmp.setPayStatus((short) 1);
        logger.info("添加支付流水, 订单号" + vo.getOrderNo() + ", 调用pay-lite模块, 查询支付流水入参request=" + JSON.toJSONString(tmp));
        Response findPaymentJournalResponse = PayService.callUnderlineFromInternal("yyt.pay.payment.journal.find",
                JsonUtils.toJsonString(tmp));
        logger.info("添加支付流水, 订单号" + vo.getOrderNo() + ", 调用pay-lite模块, 查询支付流水返回response="
                + JSON.toJSONString(findPaymentJournalResponse));
        if ("0".equals(findPaymentJournalResponse.getResultCode())) {
            logger.info("添加支付流水, 订单号" + vo.getOrderNo() + ", 支付流水已存在，不再添加。");
            return;
        }
        
        PaymentJournalVo paymentJournal=new PaymentJournalVo();
        paymentJournal.setOrgId(vo.getOrgId());
        paymentJournal.setOrgName(vo.getOrgName());
        paymentJournal.setOrgCode(vo.getOrgCode());
        paymentJournal.setBranchId(vo.getBranchId());
        paymentJournal.setBranchName(vo.getBranchName());
        paymentJournal.setOrderNo(vo.getOrderNo());
        paymentJournal.setOutOrderNo(requestVo.getOutOrderNo());
        paymentJournal.setPaymentDealId(requestVo.getPaymentDealId());
        paymentJournal.setPayAmount(vo.getPayAmount());
        paymentJournal.setMedicareAmount(vo.getMedicareAmount());
        paymentJournal.setAccountAmount(vo.getAccountAmount());
        paymentJournal.setInsuranceAmount(vo.getInsuranceAmount());
        paymentJournal.setTotalAmount(vo.getTotalAmount());
        paymentJournal.setPlatformId(vo.getPlatformId());
        paymentJournal.setPlatformCode(vo.getPlatformCode());
        paymentJournal.setPlatformName(vo.getPlatformName());
        paymentJournal.setPlatformOrgAppName(vo.getPlatformOrgAppName());
        paymentJournal.setPlatformOrgAppCode(vo.getPlatformOrgAppCode());
        paymentJournal.setPayAppId(requestVo.getPayeeAppId());
        paymentJournal.setDealAccount("");
        paymentJournal.setAccountName("");
        paymentJournal.setPayStatus((short) 1);
//        paymentJournal.setHisOrderNo(payClinicOrderVoResponse.getHisOrdNum());
        paymentJournal.setOrderType(vo.getOrderType());
        paymentJournal.setCheckStatus((short)0);
        paymentJournal.setPayTime(requestVo.getPayTime());
        
        if (requestVo.getPayMode().intValue() == 99) {
            paymentJournal.setPayMode((short) 23);
        } else if (requestVo.getPayMode().intValue() == 99) {
            paymentJournal.setPayMode((short) 13);
        } else {
            paymentJournal.setPayMode((short) requestVo.getPayMode().intValue());
        }
        
//        paymentJournal.setOrgAppCode(vo.getOrgAppCode());
        paymentJournal.setPlatformOrgAppCode(vo.getPlatformOrgAppCode());
        paymentJournal.setBranchId(vo.getBranchId());
        paymentJournal.setBranchName(vo.getBranchName());
        paymentJournal.setSettlementStatus((short) 0);
        if (requestVo.getInsuranceMode() != null) {
            paymentJournal.setInsuranceMode(requestVo.getInsuranceMode());
        }
        paymentJournal.setBranchId(vo.getBranchId());
        paymentJournal.setBranchName(vo.getBranchName());
        paymentJournal.setBranchCode(vo.getBranchCode());
        
        logger.info("添加支付流水, 订单号" + vo.getOrderNo() + ", 调用pay-lite模块, 增加支付流水入参request="
                + JSON.toJSONString(paymentJournal));
        Response addPaymentJournalResponse = PayService.callUnderlineFromInternal("yyt.pay.payment.journal.add",
                JsonUtils.toJsonString(paymentJournal));
        logger.info("添加支付流水, 订单号" + vo.getOrderNo() + ", 调用pay-lite模块, 增加支付流水返回response="
                + JSON.toJSONString(addPaymentJournalResponse));
    }
    
    /**
     * 门诊支付写单 - 外部接口 yyt.clinic.pay.order.by.order.no.out.ack
     * @param data
     * @param sessionId
     * @return
     */
    public Response ackPayOrderByOrderNoOut(String data, String sessionId) {
        Response response = new Response();

        logger.info("门诊根据订单号支付写单, 方法入参data:" + data);

        // 转换成-->RequestVo
        AckPayOrderOutVoRequest requestVo = JsonUtils.parseObject(data, AckPayOrderOutVoRequest.class);

        // 找出对应数据库保存的门诊记录getOrderByOrderNo
        Map<String, String> dataMap = new HashMap<String, String>();
        dataMap.put("order_no", requestVo.getYytOrderNo());
        dataMap.put("org_id", requestVo.getOrgId()); 
        logger.info("门诊根据订单号支付写单, 订单号" + requestVo.getYytOrderNo() + ", 调base模块, 查询订单接口入参request="
                + JSON.toJSONString(dataMap));
        Response ordResponse = BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.by.order.no.out.get",
                JsonUtils.toJsonString(dataMap));
        logger.info("门诊根据订单号支付写单, 订单号" + requestVo.getYytOrderNo() + ", 调base模块, 查询订单接口返回response="
                + JSON.toJSONString(ordResponse));

        if (!"0".equals(ordResponse.getResultCode())) {
            response.setResultCodeAndMessage("3000", "查询订单失败。");
            return response;
        }
        OrderExtVo vo = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);
        requestVo.setHospitalCode(vo.getOrgCode());
        requestVo.setOutOrderNo(requestVo.getYytOrderNo());
        requestVo.setPaymentDealId(vo.getPaymentDealId());
        if (requestVo.getIsFromInner() != null) {
            requestVo.setIsFromInner(requestVo.getIsFromInner());
        } else {
            JSONObject jsonObject = JSON.parseObject(vo.getExtraParams());
            String isFromInner = jsonObject.getString("is_from_inner");
            if (StringUtils.isNotBlank(isFromInner)) {
                requestVo.setIsFromInner(Integer.parseInt(isFromInner));
            }
        }
        
        if (vo.getInsuranceMode() != null) {
            requestVo.setInsuranceMode(vo.getInsuranceMode());
        }

        if (requestVo.getPayMode() == null
                || (requestVo.getPayMode().intValue() != 22 && requestVo.getPayMode().intValue() != 21 && requestVo.getPayMode().intValue() != 27
                && requestVo.getPayMode().intValue() != 12 && requestVo.getPayMode().intValue() != 16&&requestVo.getPayMode().intValue() != 8
                && requestVo.getPayMode().intValue() != 11 && requestVo.getPayMode().intValue() != 31)) {
            requestVo.setPayMode(99);
        }
        if(StringUtils.isNotBlank(requestVo.getOrgId())) {
            requestVo.setPayAmount(0);
        }

        logger.info("门诊根据订单号支付写单, 订单号" + requestVo.getYytOrderNo() + ", 调用门诊支付写单外部接口");
        return ackPayOrderOut(JsonUtils.toJsonString(requestVo), sessionId);
    }
    
    public Response getPayDetail(String data, String sessionId) {
        logger.info("getPayDetail, request data=" + data + ", sessionId=" + sessionId);
        Response response = new Response();
        
        ClinicVo clinicVo = JsonUtils.parseObject(data, ClinicVo.class);
        
        PayDetailVo payDetailVo = new PayDetailVo();
        payDetailVo.setBranchCode(clinicVo.getBranchCode());
        payDetailVo.setHospitalCode(clinicVo.getHospitalCode());
        payDetailVo.setSessionId(sessionId);
        payDetailVo.setHisOrdNum(clinicVo.getPsOrdnum());
        logger.info("getMZFeeDetail, getClinicPayDetail request=" + JSON.toJSONString(payDetailVo));
        ResCommon<List<PayDetailVoResponse>> payDetailResponse = HisifaceService.getHisifaceClient()
                .getClinicPayDetail(payDetailVo);
        logger.info("getMZFeeDetail, getClinicPayDetail response=" + JSON.toJSONString(payDetailResponse));
        if (!ResCommon.SUCCESS_CODE.equals(payDetailResponse.getResultCode())) {
            response.setResultCodeAndMessage("3000",
                    "查询就订单号" + clinicVo.getPsOrdnum() + "对应的已缴费明细失败：" + payDetailResponse.getResultMessage() + "！");
            return response;
        }
        List<PayDetailVoResponse> payDetailVoResponses = new ArrayList<PayDetailVoResponse>();
        List<PayDetailVoResponse> payDetailVos = JsonUtils.parseObject(payDetailResponse.getResult(), List.class);
        for (int i = 0; i < payDetailVos.size(); i++) {
            PayDetailVoResponse payDetail = new PayDetailVoResponse();
            PayDetailVoResponse payDetailTmp = JsonUtils.parseObject(
                    JSON.toJSONString(payDetailVos.get(i)), PayDetailVoResponse.class);
            BeanUtils.copyProperties(payDetailTmp, payDetail);
            
            payDetailVoResponses.add(payDetail);
        }
        response.setResult(JsonUtils.toJsonString(payDetailVoResponses));
        return response;
    }
    
    private void addOrderToExceptionList(OrderExtVo vo , String resultMessage) {
        logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 订单order=" + JSON.toJSONString(vo));
        boolean isAdd = true;
        try {
            logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 调用base模块, 查询是否已经存在异常单入参request=" + JSON.toJSONString(vo));
            Response response = BaseService.callUnderlineFromInternal("yyt.base.order.exception.by.order.no.get",
                    JsonUtils.toJsonString(vo));
            logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 调用base模块, 查询是否已经存在异常单返回response=" + JSON.toJSONString(response));
            if (!"0".equals(response.getResultCode())) {
                logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 调用base模块, 查询异常单信息失败");
            }

            OrderExceptionVo oe = JsonUtils.parseObject(response.getResult(), OrderExceptionVo.class);
            if (oe != null) {
                isAdd = false;
            }
        } catch (Exception e) {
            logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 查询异常单是否存在报错。");
        }
        
        if (isAdd) {
            OrderExceptionVo record = new OrderExceptionVo();
            record.setBranchCode(vo.getBranchCode());
            record.setBranchId(vo.getBranchId());
            record.setBranchName(vo.getBranchName());
            record.setCreatedTime(DateUtils.dateToString(new Date()));
            record.setExceptionHandlerCount(0);
            record.setRefundHandlerCount(0);
            record.setId(PKGenerator.generateId());
            record.setIsInsurance(vo.getIsInsurance());
            record.setOrderNo(vo.getOrderNo());
            record.setOrderType(vo.getOrderType());
            record.setOrgCode(vo.getOrgCode());
            record.setOrgId(vo.getOrgId());
            record.setOrgName(vo.getOrgName());
            record.setPlatformCode(vo.getPlatformCode());
            record.setPlatformId(vo.getPlatformId());
            record.setPlatformName(vo.getPlatformName());
            record.setPlatformOrgAppCode(vo.getPlatformOrgAppCode());
            record.setUpdateTime(DateUtils.dateToString(new Date()));
            record.setHandlerResult((short) 0);
            record.setHisQueryState((short) 0);
            record.setInsuranceHandlerFlag((short) 0);
            record.setSelfPayHandlerFlag((short) 0);
            record.setExceptionReason(resultMessage);
            record.setExceptionClass("Clinic-PayServiceImpl");

            logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 调用base模块, 添加异常单record=" + JSON.toJSONString(record));
            CacheService.setGlobalKey(CacheConstant.CACHE_CLINIC_MODULE, CacheConstant.CACHE_CLINIC_PAY_EXCEPTION_ORDER,
                    record.getOrderNo(), JSON.toJSONString(record), CacheConstant.CACHE_NOT_EXPIRETIME);

            logger.info("添加异常单信息, 异常原因：" + resultMessage);

            BaseService.callUnderlineFromInternal("", "yyt.base.order.exception.add", JsonUtils.toJsonString(record));
        }
        logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 结束");
    }


    /**
     * 门诊异常确认 - 外部接口 yyt.clinic.pay.clinic.exception.ack
     * @author zhangkewen
     * @param data
     * @param sessionId
     * @return
     */
    public Response ackPayClinicException(String data, String sessionId) {
        logger.info("门诊异常确认 - 外部接口-->method:ackPayClinicException,data:" + data + "！");

        Response response = new Response();
        // 转换成-->RequestVo
        AckPayOrderOutVoRequest requestVo = JsonUtils.parseObject(data, AckPayOrderOutVoRequest.class);

        // 找出对应数据库保存的门诊记录getOrderByOrderNo
        Map<String, String> dataMap = new HashMap<String, String>();
        dataMap.put("order_no", requestVo.getYytOrderNo());

        Response ordResponse = BaseService.callUnderlineFromInternal(sessionId, "yyt.base.order.by.order.no.out.get",
                JsonUtils.toJsonString(dataMap));
        logger.info("ackPayClinicException, yyt.base.order.by.order.no.out.get ordResponse=" + JSON.toJSONString(ordResponse));
        if (!"0".equals(ordResponse.getResultCode())) {
            response.setResultCodeAndMessage("3000", "查询订单失败。");
            return response;
        }
        OrderExtVo order = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);

        // 门诊缴费异常确认
        AckClinicExceptionVo ackClinicExceptionVo = new AckClinicExceptionVo();
        ackClinicExceptionVo.setHospitalCode(order.getOrgCode());
        ackClinicExceptionVo.setPatCardNo(order.getMedicalCardNo());
        ackClinicExceptionVo.setPatCardType(String.valueOf(order.getMedicalCardType()));
        ackClinicExceptionVo.setAgtCode("");
        ackClinicExceptionVo.setAgtOrdNum("");
        ackClinicExceptionVo.setHisNum(order.getHisOrderNo());
        ackClinicExceptionVo.setPayAmount(String.valueOf(order.getPayAmount()));
        String payDate = "";
        if (order.getPayTime() != null) {
            payDate = DateUtils.getDateStr(DateUtils.StringToDate(order.getPayTime()));
        } else if (order.getCreatedTime() != null) {
            payDate = DateUtils.getDateStr(DateUtils.StringToDate(order.getCreatedTime()));
        } else {
            payDate = "";
        }
        ackClinicExceptionVo.setBeginDate(payDate);
        ackClinicExceptionVo.setEndDate(DateUtils.getDateStr(new Date()));

        ResCommon<AckClinicExceptionVoResponse> resCommon = HisifaceService.getHisifaceClient().ackClinicException(ackClinicExceptionVo);
        logger.info("ackPayClinicException, request={},response={}" , JSON.toJSONString(ackClinicExceptionVo),JSON.toJSONString(resCommon));
        if ("0".equals(resCommon.getResultCode())) {
            logger.info("异常单重新发起支付后确认his订单 成功, orderNo:{}.", new Object[] { order.getOrderNo() });
            AckClinicExceptionVoResponse ackClinicExceptionVoResponse = resCommon.getResult();

             /* 1.更新门诊订单的状态*/
            order.setHisOrderNo(ackClinicExceptionVoResponse.getHisOrdNum());
            order.setHisMessage(ackClinicExceptionVoResponse.getHisMessage());
            order.setBarcode(ackClinicExceptionVoResponse.getBarCode());
            order.setReceiptNum(ackClinicExceptionVoResponse.getReceiptNum());
            order.setOutOrderNo(requestVo.getOutOrderNo());

            order.setUpdateTime(DateUtils.dateToString(new Date()));
            order.setOrderStatusSuccess();
            order.setPayStatusPayed();

            BaseService.callUnderlineFromInternal(sessionId,
                    "yyt.base.order.update", JsonUtils.toJsonString(order));
            response.setResult(JSON.toJSONString(order));
            response.setResultCodeAndMessage("0", "异常确认成功");
        }else{
            response.setResultCodeAndMessage(resCommon.getResultCode(), resCommon.getResultMessage());
        }

        return response;
    }
}
